/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.admin.service.impl;

import vip.dexian.admin.dao.DepartmentDao;
import vip.dexian.admin.dao.RoleDepartmentDao;
import vip.dexian.admin.dto.RoleDepartmentDTO;
import vip.dexian.admin.entity.Department;
import vip.dexian.admin.entity.Role;
import vip.dexian.admin.entity.RoleDepartment;
import vip.dexian.admin.manager.RoleDepartmentManager;
import vip.dexian.admin.service.RoleDepartmentService;
import vip.dexian.common.query.Filter;
import vip.dexian.common.query.Listable;
import vip.dexian.common.utils.FilterUtils;
import vip.dexian.common.utils.NumberUtils;
import vip.dexian.core.base.service.BaseServiceImpl;
import vip.dexian.core.exception.ServiceValidationException;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 角色->部门业务逻辑处理实现
 *
 * @author 挺好的 2023年06月08日 11:04:58
 */
@Service ("roleDepartmentServiceImpl")
@Slf4j
public class RoleDepartmentServiceImpl extends BaseServiceImpl <RoleDepartment, RoleDepartmentDTO, Long>
        implements RoleDepartmentService {

    /**
     * 角色->部门Dao
     */
    @Resource (name = "roleDepartmentDaoImpl")
    private RoleDepartmentDao roleDepartmentDao;

    /**
     * 部门
     */
    @Resource (name = "departmentDaoImpl")
    private DepartmentDao departmentDao;

    /**
     * 角色关联部门
     */
    @Resource (name = "roleDepartmentManagerImpl")
    private RoleDepartmentManager roleDepartmentManager;

    /**
     * 保存角色对应的部门
     *
     * @param departments
     *         角色对应的部门
     */
    @Override
    @Async
    @Transactional (rollbackFor = Exception.class)
    public void save (List <RoleDepartment> departments) {
        if (org.apache.commons.collections4.CollectionUtils.isEmpty(departments)) {
            return;
        }

        for (RoleDepartment roleDepartment : departments) {
            this.save(roleDepartment);
        }
    }

    /**
     * 根据角色id删除部门
     *
     * @param roleId
     *         角色id
     *
     * @return 删除成功的数量
     */
    @Override
    @Transactional (rollbackFor = Exception.class)
    public int deleteByRoleId (Long roleId) {
        if (!NumberUtils.isPositive(roleId)) {
            return 0;
        }
        return this.roleDepartmentDao.deleteByRoleId(roleId);
    }

    /**
     * 根据角色id查找部门
     *
     * @param roleId
     *         角色id
     *
     * @return {@link vip.dexian.admin.dto.RoleDepartmentDTO}
     */
    @Override
    @Transactional (propagation = Propagation.NOT_SUPPORTED)
    public List <RoleDepartmentDTO> findByRoleId (Long roleId) {
        if (!NumberUtils.isPositive(roleId)) {
            return Collections.emptyList();
        }

        List <Filter> filters = FilterUtils.builder().equals("roleId", roleId).build();
        Listable listable = Listable.builder().isEnableDefaultOrder(false).filters(filters).build();

        return super.findList(listable);
    }

    /**
     * 创建角色->部门对象
     *
     * @param departmentIds
     *         部门id
     * @param role
     *         关联的角色
     *
     * @return 如果 部门id 或者 role 为null，则返回empty list
     */
    @Override
    @Transactional (propagation = Propagation.NOT_SUPPORTED)
    public List <RoleDepartment> create (List <Long> departmentIds, Role role) {

        if (org.apache.commons.collections4.CollectionUtils.isEmpty(departmentIds) || role == null) {
            return Collections.emptyList();
        }

        List <Department> departments = this.departmentDao.findList(departmentIds);

        if (org.apache.commons.collections4.CollectionUtils.isEmpty(departmentIds)) {
            return Collections.emptyList();
        }

        List <RoleDepartment> roleDepartments = new ArrayList <>();

        for (Department department : departments) {
            if (Boolean.FALSE.equals(department.getIsEnabled())) {
                throw new ServiceValidationException("A20004", department.getName());
            }

            RoleDepartment roleDepartment = RoleDepartment.builder().roleId(role.getId())
                    .departmentId(department.getId()).departmentName(department.getName()).build();

            roleDepartments.add(roleDepartment);
        }

        return roleDepartments;
    }

    /**
     * 根据角色id查找关联的部门
     *
     * @param roleIds
     *         角色id
     *
     * @return 部门id列表
     */
    @Override
    @Transactional (propagation = Propagation.SUPPORTS, readOnly = true)
    public List <Long> findDepartmentIds (List <Long> roleIds) {

        if (CollectionUtils.isEmpty(roleIds)) {
            return Collections.emptyList();
        }

        // 对于IN查询，首先使用，首先对roleIds进行排序，以提升查询性能
        roleIds = roleIds.stream().distinct().sorted().toList();

        List <RoleDepartmentDTO> roleDepartments = this.roleDepartmentManager.findListByRoleIds(roleIds);

        // 去重、排序
        return roleDepartments.stream().map(RoleDepartmentDTO::getDepartmentId).distinct().sorted().toList();
    }


}
